use crate::components::component::App;
use crate::components::enums::{
    HttpMethod, HttpRequestContentType
};
use reqwest::Client;
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
use std::collections::HashMap;
use std::str::FromStr;
use std::time::Duration;

/// 定义一个自定义错误类型，以便统一处理网络和解析错误
#[derive(Debug)]
pub enum HttpError {
    Request(reqwest::Error),
    InvalidHeader(String),
}

/// 实现从 reqwest::Error 到我们自定义错误的转换
impl From<reqwest::Error> for HttpError {
    fn from(err: reqwest::Error) -> Self {
        HttpError::Request(err)
    }
}

/// 包含了请求成功后的响应数据
#[derive(Debug)]
pub struct HttpResponse {
    pub status_code: u16,
    pub headers: Vec<(String, String)>,
    pub body: String,
}

/// 执行 HTTP 请求的核心函数
pub async fn execute_request(app: &App) -> Result<HttpResponse, HttpError> {
    // <-- 2. 改为 async fn
    let client = Client::builder().timeout(Duration::from_secs(10)).build()?;

    // 1. 构建 URL
    let mut final_url = app.server_addr.clone();
    if !app.request_http_params.is_empty() && app.http_method == HttpMethod::Get {
        let query_string = app
            .request_http_params
            .iter()
            .map(|(k, v)| format!("{k}={v}"))
            .collect::<Vec<String>>()
            .join("&");
        final_url.push('?');
        final_url.push_str(&query_string);
    }

    // 2. 根据 HTTP Method 创建 RequestBuilder
    let mut request_builder = match app.http_method {
        HttpMethod::Get => client.get(&final_url),
        HttpMethod::Post => client.post(&final_url),
        HttpMethod::Put => client.put(&final_url),
        HttpMethod::Delete => client.delete(&final_url),
        HttpMethod::Patch => client.patch(&final_url),
    };

    // 3. 添加 Headers
    let mut headers = HeaderMap::new();
    for (key, value) in &app.request_http_headers {
        let header_name = HeaderName::from_str(key)
            .map_err(|_| HttpError::InvalidHeader(format!("Invalid header name: {key}")))?;
        let header_value = HeaderValue::from_str(value).map_err(|_| {
            HttpError::InvalidHeader(format!("Invalid header value for {key}: {value}"))
        })?;
        headers.insert(header_name, header_value);
    }

    // 4. 添加 Body
    if matches!(
        app.http_method,
        HttpMethod::Post | HttpMethod::Put | HttpMethod::Patch
    ) {
        if app.request_content_type == HttpRequestContentType::FormData {
            let mut form_data = HashMap::new();
            for (k, v) in &app.request_http_params {
                form_data.insert(k.clone(), v.clone());
            }
            request_builder = request_builder.form(&form_data);
        } else {
            let content_type_str = match app.request_content_type {
                HttpRequestContentType::Json => "application/json",
                HttpRequestContentType::Xml => "application/xml",
                HttpRequestContentType::Html => "text/html",
                HttpRequestContentType::Text => "text/plain",
                HttpRequestContentType::Raw => "application/octet-stream",
                HttpRequestContentType::FormData => unreachable!(),
            };
            headers.insert("Content-Type", HeaderValue::from_static(content_type_str));
            request_builder = request_builder.body(app.request_http_body.clone());
        }
    }

    request_builder = request_builder.headers(headers);

    // 5. 发送请求并处理响应
    let response = request_builder.send().await?; // <-- 3. 使用 .await

    let status_code: u16 = response.status().as_u16();

    let response_headers = response
        .headers()
        .iter()
        .map(|(name, value)| (name.to_string(), value.to_str().unwrap_or("").to_string()))
        .collect();

    let body = response.text().await?; // <-- 4. 使用 .await

    Ok(HttpResponse {
        status_code,
        headers: response_headers,
        body,
    })
}
